package com.cskaoyan.javase.oop2._1extends._4hierarchy;

import java.util.Objects;

/**
 * 问题1:
 *      Java中的一个类，能不能使用extends关键字同时直接继承多个父类呢?
 *      不能,在Java语法设计中,通过extends关键字直接继承父类,最多只能继承一个父类
 *      "直接父类只有一个"
 *      像Java这种，只能有一个直接父类，而不能有两个或更多的设计，称之为"单重继承"或者"单继承"。
 *      而像C++当中，一个类可以直接继承多个类，就称之为"多重继承"或者"多继承"。
 *      总的来说,单继承的语法设计更简单,这符合Java简化C++的原则
 *      多继承虽然更复杂,但是它会让程序设计更灵活
 *
 * 问题2:
 *      Java中的一个类，只能有一个父类吗?
 *      当然不是,因为直接父类也有直接父类,那么对于子类来说,就是有很多"间接的父类"
 *      虽然直接父类只有一个
 *      但Java中一个类仍然可以有很多个"间接父类"，因为父类可能还有父类。
 *      比如A继承B，B又继承了C，那么A的直接父类就是B，间接父类是C。
 *      于是就形成了下面几个概念：
 *          1.祖先类：处在继承顶层的类。
 *          2.继承层次（hierarchy）：由某个祖先类派生出来的所有类的集合叫做继承层次。
 *          3.继承链：从某一个子类开始，到其祖先类的路径。
 *
 *  继承层次中需要注意的地方：
 *
 * 在一条继承链中，总称呼下游类是上游类的子类，不管隔了几层。没有孙子类或者重孙类这种概念。
 * 在一条继承链中的，下游的类总是继承上游类的所有成员，不管隔了几层。
 * 在一条继承链中，下游类总可以看成一个上游类，存在"is-a"关系。
 * (重点)不在同一条继承链中的类，没有任何关系。虽然看起来像"兄弟姐妹"类，但是Java是不讲究血统的。
 *      具体来说
 *      同一条继承链中的两个类才是有父子关系的,不在同一个继承链中,没有任何关系
 *      包括引用数据类型的类型转换
 *      无论是向上转型还是向下转型 都是指在同一条继承链当中
 *
 * 因为一方面，子类可以自由扩展功能；另一方面，继承来的东西也是可以修改的。
 * 所以"兄弟姐妹"可能完全和"我"不同，没有任何关系。
 * 不能循环定义继承。比如A继承B，B继承C，再让C来继承A，这是不行的。
 * 继承链可以无限延伸下去，但是一般来说有个5~6层继承，已经很多了。
 *
 * 扩展:
 *      在Java整个继承层次当中,Object类属于继承层次中的祖先类
 *      任何类(包括数组)都继承了该类,都继承了该类的成员
 * Java代码中,某个类如果没有直接使用"extends"关键字,显式的声明它的直接父类
 *      那么它就隐式继承Object,Object类就是它的直接父类
 * 而一个类如果直接用"extends"关键字 ,显式的声明它的直接父类
 *      那么它仍然继承Object,但不是直接继承,而是间接继承
 *      因为这个类的间接父类中肯定,必然有一个类直接继承Object
 *
 * @since 09:54
 * @author wuguidong@cskaoyan.onaliyun.com
 */
// Class 'Demo' explicitly extends 'java.lang.Object' 这是一个隐式继承,无需写出来
public class Demo extends Object {
    public static void main(String[] args) {
        Grandson gs = new Grandson();
        // 以下方法是继承自Object类
        // gs.hashCode()
        gs.testGS();
        gs.testG();
        gs.testF();
        gs.testS();

        // 在一条继承链中，下游类总可以看成一个上游类，存在"is-a"关系。
        // 思考: 在本案例的类中,创建Grandson对象有几种方式? 父类引用指向子类对象
        Grandfather gf = new Grandson();
        Father fg = new Grandson();
        Son sg = new Grandson();

        Son s = new Son();
        // 不在一个继承链当中,没有任何关系
        // s.testU();

        Grandfather gff = new Grandfather();
        Father ff = (Father) gff;
        Uncle u = (Uncle) gff;

        Father f2 = new Father();
        // 不在一个继承链当中,没有任何关系
        // Uncle f21 = (Uncle) f2;

        // 数组的类型也是一个类,但这个类是JVM在底层创建的,程序员是看不到的
        int[] arr = new int[3];
        System.out.println(arr.length);
    }
}

class Grandfather {
    public void testG() {
    }
}

class Uncle extends Grandfather {
    public void testU() {
    }
}

class Father extends Grandfather {
    public void testF() {
    }
}

class Son extends Father {
    public void testS() {
    }
}

class Grandson extends Son {
    public void testGS() {
    }
}


// Class cannot extend multiple classes
// class Son extends Father,Father2{}
